using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using System.Text;
using Genghis;
using Microsoft.CSharp;
using SRGenerator.CustomTool;
using clp = Genghis.CommandLineParser;

namespace BatchSRGenerator
{

    class BatchGenerationArgs: CommandLineParser
    {
        [clp.ValueUsage("vb, cs, or CodeDom Provider assembly qualified class name.", ValueName = "CodeDomProvider", MatchPosition = true, Optional = false)]
        public string codeProvider = "cs";

        [clp.ValueUsage("Namespace.", Name = "namespace", MatchPosition = true, Optional = false)]
        public string ns = string.Empty;

        [clp.ValueUsage("File name, either a .strings file or a .resx file.", Name = "file", MatchPosition = true, Optional = false)]
        public string filename = null;        
    }


	class EntryPoint : IProcessorFeedback
	{
		[STAThread]
		static int Main(string[] args)
		{
            try
            {

                BatchGenerationArgs batchArgs = new BatchGenerationArgs();
                if (!batchArgs.ParseAndContinue(args))
                    return 1;

                EntryPoint ep = new EntryPoint();
                switch (batchArgs.codeProvider.ToLower())
                {
                    case "cs":
                        ep.SetCodeProvider(typeof(Microsoft.CSharp.CSharpCodeProvider));
                        break;

                    case "vb":
                        ep.SetCodeProvider(typeof(Microsoft.VisualBasic.VBCodeProvider));
                        break;

                    default:
                        Type tp = Type.GetType(batchArgs.codeProvider,true, true);
                        ep.SetCodeProvider(tp);
                        break;
                }

                if (!File.Exists(batchArgs.filename))
                {
                    Console.Error.WriteLine("Cannot find file: " + Path.GetFullPath(batchArgs.filename));
                    return 1;
                }

                ep.ProcessFile(batchArgs.filename, batchArgs.ns);
                if (ep.Failed)
                {
                    return 1;
                }

            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.ToString());
                return 2;
            }

            return 0;
		}

        public void SetCodeProvider(Type providerType)
        {
            _provider = (CodeDomProvider) Activator.CreateInstance(providerType);
        }

        bool _failed = false;

        public bool Failed
        {
            get
            {
                return _failed;
            }
        }

        CodeDomProvider _provider;
        string _currentFile = string.Empty;

        private void ProcessFile(string inputFileName, string ns)
        {
            Processor p = new Processor(_provider);

            _currentFile = Path.GetFullPath(inputFileName);
            if (Path.GetExtension(inputFileName).ToLower() != ".resx")
            {
                inputFileName = p.GenerateResourceFile(inputFileName, this);
            }            

            ICodeGenerator codeGenerator = _provider.CreateGenerator();

            StringBuilder sb = p.GenerateCode(inputFileName, ns, this, false);

            string outputFile = Path.Combine(Path.GetDirectoryName(inputFileName),
                Path.GetFileNameWithoutExtension(inputFileName) + "." + _provider.FileExtension);
            
            // Write to the file
            using (TextWriter tw = File.CreateText(outputFile))
            {
                tw.Write(sb);
            }

            Console.WriteLine("Generated code file:     " + outputFile);
        }

	    public void LineError(string message, string line, int lineNo)
	    {
	        Console.WriteLine("Error: {0}, at line {1} in file {2}:\n{3}\n", message, lineNo, _currentFile, line);
	    }

	    public void Information(string message)
	    {
	        Console.WriteLine(message);
	    }

	    public void AddResourceFile(string filename)
	    {
	        Console.WriteLine("Generated resource file: " + filename);
	    }

	}
}
